package Reflect;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/*
 * 
 *	类名称：PropertiesCopyUtil
 *	类描述：对象字段复制工具类
 *	创建人：fw
 *	创建时间：2016年12月22日上午9:14:00
 *	修改人：
 *	修改时间：
 *	修改备注：
 */
public class PropertiesCopyUtil {
	/**
	 * 
	 *	方法名：copyPublic
	 *	@param t 被复制类
	 *	@param s 被赋值类
	 *	@throws NoSuchFieldException
	 *	@throws SecurityException
	 *	@throws IllegalArgumentException
	 *	@throws IllegalAccessException
	 *	返回类型：void
	 *	说明：只有t和s的共有public字段复制
	 *	创建人：fw
	 * 	创建日期：2016年12月22日上午9:15:30
	 *	修改人：
	 *	修改日期：
	 */
	@SuppressWarnings("unchecked")
	public static <T, S> void copyPublic(T t, S s)
			throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
		Class<T> ct = (Class<T>) t.getClass();
		Class<S> cs = (Class<S>) s.getClass();
		Field[] tFields = ct.getFields();
		Field[] sFields = cs.getFields();
		if (tFields.length * sFields.length == 0)
			return;
		List<String> sFieldNames = new ArrayList<>();
		for (Field field : sFields) {
			sFieldNames.add(field.getName());
		}
		for (Field field : tFields) {
			if (sFieldNames.contains(field.getName())) {
				Field sField = cs.getField(field.getName());
				String sType = sField.getType().toString();
				if (field.getType().toString().equals(sType)) {
					sField.set(s, field.get(t));
				}
			}
		}
	}

	/**
	 * 
	 *	方法名：copy
	 *	@param t 被复制类
	 *	@param s 被赋值类
	 *	@throws IllegalArgumentException
	 *	@throws IllegalAccessException
	 *	@throws NoSuchFieldException
	 *	@throws SecurityException
	 *	返回类型：void
	 *	说明：t和s共有字段复制，包括的字段访问限制符有：public、protect、private、friendly
	 *	创建人：fw
	 * 	创建日期：2016年12月22日上午9:20:42
	 *	修改人：
	 *	修改日期：
	 */
	@SuppressWarnings("unchecked")
	public static <T, S> void copy(T t, S s)
			throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
		Class<T> ct = (Class<T>) t.getClass();
		Class<S> cs = (Class<S>) s.getClass();
		Field[] tFields = ct.getDeclaredFields();
		Field[] sFields = cs.getDeclaredFields();
		if (tFields.length * sFields.length == 0)
			return;
		for (Field field : tFields) {
			for (Field fd : sFields) {
				if (fd.getName().equals(field.getName()) && field.getType().equals(fd.getType())) {
					field.setAccessible(true);
					fd.setAccessible(true);
					fd.set(s, field.get(t));
				}
			}
		}
	}

	public static void main(String[] args) {
		ReflectEntity cFor = new ReflectEntity();
		ReflectEntity2 cTo = new ReflectEntity2();
		cFor.setSs("cFor");
		cFor.setTt(7);
		cFor.setSs1("ss1");
		TestEntity testEntity = new TestEntity();
		testEntity.setSs("testEntity");
		testEntity.setReflectEntity(cFor);
		cFor.setTestEntity(testEntity);
		try {
			copyPublic(cFor, cTo);
			copy(cFor, cTo);
			System.out.println(cTo.getTestEntity() == cTo.getTestEntity().getReflectEntity().getTestEntity());
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}

}
